package com.nan.gbd.library.codec.surface;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.opengl.GLSurfaceView;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.WindowManager;

import com.nan.gbd.library.codec.surface.camera.CameraHolder;
import com.nan.gbd.library.codec.surface.camera.CameraListener;
import com.nan.gbd.library.codec.surface.camera.CameraUtils;
import com.nan.gbd.library.codec.surface.camera.exception.CameraDisabledException;
import com.nan.gbd.library.codec.surface.camera.exception.CameraHardwareException;
import com.nan.gbd.library.codec.surface.camera.exception.CameraNotSupportException;
import com.nan.gbd.library.codec.surface.camera.exception.NoCameraException;
import com.nan.gbd.library.codec.utils.WeakHandler;

/**
 * 视图预览
 */
public class CameraSurfaceView extends EglSurfaceView implements CameraFBORender.OnSurfaceListener {

    private CameraFBORender render;
    private int cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
    private int textureId;
    private OnCameraListener mOnPreviewListener;
    private Context context;
    private WeakHandler mHandler = new WeakHandler(Looper.getMainLooper());

    public CameraSurfaceView(Context context) {
        this(context, null);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        this.context = context;
        render = new CameraFBORender(context);
        render.setOnSurfaceListener(this);
        setSurfaceRender(render);

        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

        previewAngle(context);
    }

    public void setmOnPreviewListener(OnCameraListener mOnPreviewListener) {
        this.mOnPreviewListener = mOnPreviewListener;
    }

    @Override
    public void onSurfaceCreate(SurfaceTexture surfaceTexture, int fboTextureId) {
        startCameraPreview(surfaceTexture);
        this.textureId = fboTextureId;
    }

    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
//        requestRender();
    }

    private void startCameraPreview(SurfaceTexture mSurfaceTexture) {
        Log.e("Camera","startCameraPreview................................");
        try {
            CameraUtils.checkCameraService(getContext());
        } catch (CameraDisabledException e) {
            postOpenCameraError(CameraListener.CAMERA_DISABLED);
            e.printStackTrace();
            return;
        } catch (NoCameraException e) {
            postOpenCameraError(CameraListener.NO_CAMERA);
            e.printStackTrace();
            return;
        }
        CameraHolder.State state = CameraHolder.instance().getState();
        CameraHolder.instance().setSurfaceTexture(mSurfaceTexture);
        if (state != CameraHolder.State.PREVIEW) {
            try {
                CameraHolder.instance().openCamera();
                CameraHolder.instance().startPreview();
                if (mOnPreviewListener != null) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mOnPreviewListener.openCameraSuccess(CameraHolder.instance().getCameraData().cameraWidth, CameraHolder.instance().getCameraData().cameraHeight);
                        }
                    });
                }
            } catch (CameraHardwareException e) {
                e.printStackTrace();
                postOpenCameraError(CameraListener.CAMERA_OPEN_FAILED);
            } catch (CameraNotSupportException e) {
                e.printStackTrace();
                postOpenCameraError(CameraListener.CAMERA_NOT_SUPPORT);
            }
        }
    }

    public void releaseCamera() {
        CameraHolder.instance().releaseCamera();
        CameraHolder.instance().release();
    }

    private void postOpenCameraError(final int error) {
        if (mOnPreviewListener != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mOnPreviewListener != null) {
                        mOnPreviewListener.openCameraFaile();
                    }
                }
            });
        }
    }

    public void previewAngle(Context context) {
        int angle = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
        render.resetMatrix();
        switch (angle) {
            case Surface.ROTATION_0:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
//                    render.setAngle(90, 0, 0, 1);
                    render.setAngle(180, 1, 0, 0);
                } else {
                    render.setAngle(90f, 0f, 0f, 1f);
                }
                break;
            case Surface.ROTATION_90:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(180, 0, 0, 1);
                    render.setAngle(180, 0, 1, 0);
                } else {
                    render.setAngle(90f, 0f, 0f, 1f);
                }
                break;
            case Surface.ROTATION_180:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(90f, 0.0f, 0f, 1f);
                    render.setAngle(180f, 0.0f, 1f, 0f);
                } else {
                    render.setAngle(-90, 0f, 0f, 1f);
                }
                break;
            case Surface.ROTATION_270:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(180f, 0.0f, 1f, 0f);
                } else {
                    render.setAngle(0f, 0f, 0f, 1f);
                }
                break;
        }
    }

    public int getTextureId() {
        return textureId;
    }

    public int getCameraPreviewWidth() {
        return CameraHolder.instance().getCameraData().cameraWidth;
    }

    public int getCameraPreviewHeight() {
        return CameraHolder.instance().getCameraData().cameraHeight;
    }

    public void setFlashMode() {
        CameraHolder.instance().switchLight();
    }

    /**
     * 摄像头切换
     */
    public void switchCamera() {
        CameraHolder.instance().switchCamera();
        previewAngle(context);
    }

    /**
     * 获取当前相机预览缩放值
     */
//    public int getZoomValue(int scaleRatio) {
//        return cameraManager.getZoomValue(scaleRatio);
//    }

    /**
     * 设置SeekBar拖动值
     *
     * @param zoomValue int
     */
//    public void setZoomValue(int zoomValue) {
//        cameraManager.setZoomValue(zoomValue);
//    }

    /**
     * 设置滤镜类型
     *
     * @param type ：int
     */
    public void setType(int type) {
        render.setType(type);
    }

    public int getType() {
        return render.getType();
    }

    /**
     * 设置滤镜颜色
     *
     * @param color ：float
     */
    public void setColor(float[] color) {
        render.setColor(color);
    }

    public float[] getColor() {
        return render.getColor();
    }
}
